package com.geek.water.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geek.water.entity.Area;
import com.geek.water.entity.Customer;
import com.geek.water.entity.Site;
import com.geek.water.exception.WaterException;
import com.geek.water.mapper.SiteMapper;
import com.geek.water.service.AreaService;
import com.geek.water.service.CustomerService;
import com.geek.water.service.SiteService;
import com.geek.water.vo.AreaTreeVO;
import com.geek.water.vo.HierarchyNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author yangwenqi
 * @decs TODO
 * @date 2025/7/28
 */
@Service
public class SiteServiceImpl extends ServiceImpl<SiteMapper, Site> implements SiteService {

    @Autowired
    private AreaService areaService;

    @Autowired
    @Lazy  // 添加 @Lazy 注解
    private CustomerService customerService;

    @Override
    public void validateSiteBeforeDelete(Long siteId) {
        // 检查是否有关联区域
        if (hasAssociatedAreas(siteId)) {
            throw new WaterException("站点存在关联区域，无法删除");
        }
    }

    private boolean hasAssociatedAreas(Long siteId) {
        return areaService.lambdaQuery()
                .eq(Area::getSiteId, siteId)
                .count() > 0;
    }

    @Override
    public List<AreaTreeVO> getAreaTree(Long siteId) {
        List<Area> areas = areaService.lambdaQuery()
                .eq(Area::getSiteId, siteId)
                .list();
        return areaService.buildAreaTree(areas); // 使用AreaService构建树
    }

    @Override
    public List<HierarchyNode> getFullHierarchy() {
        List<HierarchyNode> hierarchy = new ArrayList<>();

        // 获取所有客户
        List<Customer> customers = customerService.list();

        for (Customer customer : customers) {
            HierarchyNode customerNode = new HierarchyNode();
            customerNode.setId("customer_" + customer.getId());
            customerNode.setName(customer.getName());
            customerNode.setType("customer");
            customerNode.setChildren(new ArrayList<>());

            // 获取该客户的站点
            List<Site> sites = baseMapper.findSitesByCustomerId(customer.getId());
            for (Site site : sites) {
                HierarchyNode siteNode = new HierarchyNode();
                siteNode.setId("site_" + site.getId());
                siteNode.setName(site.getName());
                siteNode.setType("site");
                siteNode.setChildren(new ArrayList<>());

                // 获取该站点的所有区域
                List<Area> allAreas = areaService.lambdaQuery()
                        .eq(Area::getSiteId, site.getId())
                        .list();

                // 构建区域树
                List<HierarchyNode> areaNodes = buildAreaHierarchy(allAreas);
                siteNode.getChildren().addAll(areaNodes);

                customerNode.getChildren().add(siteNode);
            }

            hierarchy.add(customerNode);
        }

        return hierarchy;
    }

    /**
     * 递归构建区域层级关系
     */
    private List<HierarchyNode> buildAreaHierarchy(List<Area> areas) {
        List<HierarchyNode> result = new ArrayList<>();

        // 创建区域节点映射
        Map<Long, HierarchyNode> nodeMap = new HashMap<>();
        for (Area area : areas) {
            HierarchyNode areaNode = new HierarchyNode();
            areaNode.setId(area.getId().toString());
            areaNode.setName(area.getName());
            areaNode.setType("area");
            areaNode.setChildren(new ArrayList<>());
            nodeMap.put(area.getId(), areaNode);
        }

        // 构建父子关系
        for (Area area : areas) {
            if (area.getParentAreaId() == null || area.getParentAreaId() == 0L) {
                // 根区域
                result.add(nodeMap.get(area.getId()));
            } else {
                // 子区域，添加到父区域
                HierarchyNode parent = nodeMap.get(area.getParentAreaId());
                if (parent != null) {
                    parent.getChildren().add(nodeMap.get(area.getId()));
                }
            }
        }

        return result;
    }

    @Override
    public List<Site> getMapMarkers(Long customerId) {
        LambdaQueryWrapper<Site> query = new LambdaQueryWrapper<>();
        query.eq(Site::getShowOnMap, true)
                .isNotNull(Site::getLatitude)
                .isNotNull(Site::getLongitude);

        if (customerId != null) {
            query.eq(Site::getCustomerId, customerId);
        }

        return this.list(query);
    }

    @Override
    public boolean batchUpdateMapPositions(List<Site> sites) {
        return this.updateBatchById(sites);
    }

    @Override
    public List<Site> getCustomerMarkers(Long customerId) {
        LambdaQueryWrapper<Site> query = new LambdaQueryWrapper<>();
        query.eq(Site::getCustomerId, customerId)
                .eq(Site::getShowOnMap, true)
                .isNotNull(Site::getLatitude)
                .isNotNull(Site::getLongitude);

        return this.list(query);
    }

    @Override
    public List<Site> getSitesByBounds(Double minLat, Double maxLat, Double minLng, Double maxLng) {
        LambdaQueryWrapper<Site> query = new LambdaQueryWrapper<>();
        query.between(Site::getLatitude, minLat, maxLat)
                .between(Site::getLongitude, minLng, maxLng)
                .eq(Site::getShowOnMap, true);

        return this.list(query);
    }
}